home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / ixtrace / ixtrace-1.1.c < prev    next >
C/C++ Source or Header  |  1994-01-24  |  31KB  |  902 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Changed to avoid buffer overflows by J. Hoehle and
  5.  *  restricted output length for: str(n)cat, strlen
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <string.h>
  26. #include <sys/tracecntl.h>
  27. #include <signal.h>
  28. #include <fcntl.h>
  29. #include <sys/ioctl.h>
  30. #include <sys/ioctl_compat.h>
  31. #include <sys/termios.h>
  32. #include <exec/types.h>
  33. #include <libraries/dos.h>
  34.  
  35. #include <inline/exec.h>
  36. extern struct MsgPort *CreatePort (char *, int);
  37. extern void DeletePort (struct MsgPort *);
  38.  
  39. #define OUT_WIDTH  80    /* big enough (>30) to hold first information */
  40. #define LWS  ".35"    /* output Limited argument Width */
  41.             /* Requires compiler string concatenation (ANSI-C) */
  42.  
  43. void print_call (FILE *output, struct trace_packet *tp);
  44.  
  45. int print_all = 0;
  46. int skip_sigsetmask = 0;
  47. FILE *output;
  48.  
  49. void
  50. dummy_handler ()
  51. {
  52. }
  53.  
  54. int
  55. main (int argc, char *argv[])
  56. {
  57.   char *logfile = "-";
  58.   struct trace_packet tp = { 0,};
  59.   struct MsgPort *mp;
  60.   int c, in = 0;
  61.  
  62.   signal (SIGMSG, dummy_handler);
  63.  
  64.   while ((c = getopt (argc, argv, "aimo:p:s:")) != EOF)
  65.     switch (c)
  66.       {
  67.       case 'a':
  68.     print_all = 1;
  69.     break;
  70.  
  71.       case 'i':
  72.     in = 1;
  73.     break;
  74.  
  75.       case 'm':
  76.     skip_sigsetmask = 1;
  77.     break;
  78.  
  79.       case 'o':
  80.     logfile = optarg;
  81.     break;
  82.  
  83.       case 'p':
  84.     tp.tp_pid = atoi (optarg);
  85.     break;
  86.     
  87.       case 's':
  88.         tp.tp_syscall = atoi (optarg);
  89.         break;
  90.  
  91.       default:
  92.     fprintf (stderr, 
  93.          "%s [-a] [-m] [-o logfile] [-p pid] [-s syscall-number]\n"
  94.          "  -a  trace all calls (else __-calls are skipped)\n"
  95.          "  -i  trace entry to functions. Default is exit.\n"
  96.          "  -m  skip sigsetmask() calls (they're heavily used inside the library)\n"
  97.          "  -o  log output to logfile (default is stdout)\n"
  98.          "  -p  only trace process pid (default is to trace all processes)\n"
  99.          "  -s  only trace this syscall (default is to trace all calls)\n",
  100.          argv[0]);
  101.         return 1;
  102.       }
  103.  
  104.   if (logfile[0] == '-' && !logfile[1])
  105.     output = stdout;
  106.   else
  107.     output = fopen (logfile, "w");
  108.  
  109.   if (!output)
  110.     {
  111.       perror ("fopen");
  112.       return 1;
  113.     }
  114.  
  115.   if ((mp = CreatePort (0, 0)))
  116.     {
  117.       tp.tp_tracer_port = mp;
  118.       if (tracecntl (TRACE_INSTALL_HANDLER, &tp) == 0)
  119.     {
  120.       while (1)
  121.         {
  122.           struct Message *msg;
  123.           long sigs;
  124.  
  125.           sigs = Wait ((1 << mp->mp_SigBit) | SIGBREAKF_CTRL_C);
  126.           while ((msg = GetMsg (mp)))
  127.         {
  128.               if (msg != (struct Message *) &tp)
  129.             {
  130.               fprintf (stderr, "Got alien message! Don't do that ever again ;-)\n");
  131.             } 
  132.               else
  133.             {
  134.               if (in)
  135.             tp.tp_action = TRACE_ACTION_JMP;
  136.               if (! tp.tp_is_entry || tp.tp_action == TRACE_ACTION_JMP)
  137.                 print_call (output, &tp);
  138.             }
  139.               Signal ((struct Task *) msg->mn_ReplyPort, SIGBREAKF_CTRL_E);
  140.             }
  141.           if (sigs & SIGBREAKF_CTRL_C)
  142.         break;
  143.         }
  144.       tracecntl (TRACE_REMOVE_HANDLER, &tp);
  145.     }
  146.       else
  147.     perror ("tracecntl");
  148.       
  149.       DeletePort (mp);
  150.     }
  151.   else
  152.     perror ("CreatePort");
  153. }
  154.  
  155. void vp (), vp_fcntl (), vp_ioctl (), vp_open (), vp_pipe ();
  156.  
  157.  
  158. struct call {
  159.   int  interesting;
  160.   char *name;
  161.   void (*func)(...);
  162.   char *fmt;
  163.   char *rfmt;
  164. } call_table[] = {
  165.   { 1, "bad call",    vp,    "",        "",        },
  166.   { 1, "abort",    vp,    "()",        "",        },
  167.   { 1, "abs",    vp,    "(%d)",        "%d",        },
  168.   { 1, "access",    vp,    "(\"%s\", %d)",    "%d",        },
  169.   { 1, "alarm",    vp,    "(%d)",        "%d",        },
  170.   { 1, "atexit",    vp,    "($%lx)",    "%d",        },
  171.   { 1, "atof",    vp,    "(\"%s\")",        "%g",        },
  172.   { 1, "atoi",    vp,    "(\"%s\")",        "%d",        },
  173.   { 1, "atol",    vp,    "(\"%s\")",        "%d",        },
  174.   { 1, "bcmp",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  175.   { 1, "bcopy",    vp,    "($%lx, $%lx, %d)",    "",        },
  176.   { 1, "bsearch",    vp,    "($%lx, $%lx, %d, %d, $%lx)",     "$%lx",        },
  177.   { 1, "bzero",    vp,    "($%lx, %d)",    "",        },
  178.   { 1, "calloc",    vp,    "(%d, %d)",    "$%lx",        },
  179.   { 1, "cfgetispeed",vp,    "($%lx)",    "%d",        },
  180.   { 1, "cfgetospeed",vp,    "($%lx)",    "%d",        },
  181.   { 1, "cfmakeraw",    vp,    "($%lx)",    "%d",        },
  182.   { 1, "cfree",    vp,    "($%lx)",    "",        },
  183.   { 1, "cfsetispeed",vp,    "($%lx)",    "%d",        },
  184.   { 1, "cfsetospeed",vp,    "($%lx)",    "%d",        },
  185.   { 1, "cfsetspeed",    vp,    "($%lx)",    "%d",        },
  186.   { 1, "chdir",    vp,    "(\"%s\")",        "%d",        },
  187.   { 1, "chmod",    vp,    "(\"%s\", %o)",    "%d",        },
  188.   { 1, "chown",    vp,    "(\"%s\", %d, %d)",    "%d",        },
  189.   { 1, "clock",    vp,    "()",        "%d",        },
  190.   { 1, "close",    vp,    "(%d)",        "%d",        },
  191.   { 1, "creat",    vp,    "(\"%s\", %o)",    "%d",        },
  192.   { 1, "CreateExtIO",vp,    "($%lx, %d)",    "$%lx",        },
  193.   { 1, "CreatePort",    vp,    "(\"%s\", %d)",    "$%lx",        },
  194.   { 1, "CreateStdIO",vp,    "($%lx)",    "$%lx",        },
  195.   { 1, "CreateTask",    vp,    "(\"%s\", %d, $%lx, %d)",    "$%lx",        },
  196.   { 1, "DeleteExtIO",vp,    "($%lx)",    "",        },
  197.   { 1, "DeletePort",    vp,    "($%lx)",    "",        },
  198.   { 1, "DeleteStdIO",vp,    "($%lx)",    "",        },
  199.   { 1, "DeleteTask",    vp,    "($%lx)",    "",        },
  200.   { 1, "difftime",    vp,    "(%d, %d)",    "%d",        },
  201.   { 1, "div",    vp,    "(%d, %d)",    "%d",        },
  202.   { 1, "dup",    vp,    "(%d)",        "%d",        },
  203.   { 1, "dup2",    vp,    "(%d, %d)",    "%d",        },
  204.   { 1, "exit",    vp,    "(%d)",        "",        },
  205.   { 1, "fchmod",    vp,    "(%d, %o)",    "%d",        },
  206.   { 1, "fcntl",    vp_fcntl,    "(%d, \"%s\", %d)", "%d",        },
  207.   { 1, "ffs",    vp,    "(%d)",        "%d",        },
  208.   { 1, "flock",    vp,    "(%d, %d)",    "%d",        },
  209.   { 1, "free",    vp,    "($%lx)",    "",        },
  210.   { 1, "frexp",    vp,    "(%g, %g)",    "%g",        },
  211.   { 1, "fstat",    vp,     "(%d, $%lx)",    "%d",        },
  212.   { 1, "fsync",    vp,    "(%d)",        "%d",        },
  213.   { 1, "ftime",    vp,    "(%d)",        "%d",        },
  214.   { 1, "ftruncate",    vp,    "(%d, %d)",    "%d",        },
  215.   { 1, "getcwd",    vp,    "(\"%s\", %d)",    "%d",        },
  216.   { 1, "getdtablesize",vp,    "()",        "%d",        },
  217.   { 1, "getegid",    vp,    "(%d)",        "%d",        },
  218.   { 1, "getenv",    vp,    "(\"%s\")",        "\"%s\"",        },
  219.   { 1, "geteuid",    vp,    "()",        "%d",        },
  220.   { 1, "getgid",    vp,    "()",        "%d",        },
  221.   { 1, "getgrgid",    vp,    "()",        "%d",        },
  222.   { 1, "getgroups",    vp,    "(%d, $%lx)",    "%d",        },
  223.   { 1, "gethostname",vp,    "(\"%s\", %d)",    "%d",        },
  224.   { 1, "getitimer",    vp,    "(%d, $%lx)",    "%d",        },
  225.   { 1, "getpagesize",vp,    "()",        "%d",        },
  226.   { 1, "getpgrp",    vp,    "(%d)",        "%d",        },
  227.   { 1, "getpid",    vp,    "()",        "$%lx",        },
  228.   { 1, "getppid",    vp,    "()",        "$%lx",        },
  229.   { 1, "getpriority",vp,    "(%d, %d)",    "%d",        },
  230.   { 1, "getpwnam",    vp,    "(\"%s\")",        "$%lx",        },
  231.   { 1, "getpwuid",    vp,    "(%d)",        "$%lx",        },
  232.   { 1, "getrlimit",    vp,    "(%d, $%lx)",    "%d",        },
  233.   { 1, "getrusage",    vp,    "(%d, $%lx)",    "%d",        },
  234.   { 1, "gettimeofday",vp,    "($%lx, $%lx)",    "%d",        },
  235.   { 1, "getuid",    vp,    "()",        "%d",        },
  236.   { 1, "getwd",    vp,    "(\"%s\")",        "%d",        },
  237.   { 1, "index",    vp,    "(\"%s\", %c)",    "$%lx",        },
  238.   { 1, "initgroups",    vp,    "(\"%s\", %d)",    "%d",        },
  239.   { 1, "insque",    vp,    "($%lx, $%lx)",    "",        },
  240.   { 1, "ioctl",        vp_ioctl,    "(%d, $%lx, $%lx)", "%d",        },
  241.   { 1, "isalnum",    vp,    "(%c)",        "%d",        },
  242.   { 1, "isalpha",    vp,    "(%c)",        "%d",        },
  243.   { 1, "isatty",    vp,    "(%d)",        "%d",        },
  244.   { 1, "iscntrl",    vp,    "(%c)",        "%d",        },
  245.   { 1, "isdigit",    vp,    "(%c)",        "%d",        },
  246.   { 1, "isgraph",    vp,    "(%c)",        "%d",        },
  247.   { 1, "islower",    vp,    "(%c)",        "%d",        },
  248.   { 1, "isprint",    vp,    "(%c)",        "%d",        },
  249.   { 1, "ispunct",    vp,    "(%c)",        "%d",        },
  250.   { 1, "isspace",    vp,    "(%c)",        "%d",        },
  251.   { 1, "isupper",    vp,    "(%c)",        "%d",        },
  252.   { 1, "isxdigit",    vp,    "(%c)",        "%d",        },
  253.   { 1, "ix_startup",    vp,    "(\"%s\", %d, %d, \"%s\", $%lx, $%lx)", "%d",        },
  254.   { 1, "kill",    vp,    "($%lx, %d)",    "%d",        },
  255.   { 1, "killpg",    vp,    "($%lx, %d)",    "%d",        },
  256.   { 1, "labs",    vp,    "(%d)",        "%d",        },
  257.   { 1, "ldiv",    vp,    "(%d, %d)",    "%d",        },
  258.   { 1, "link",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  259.   { 1, "longjmp",    vp,    "($%lx, %d)",    "%d",        },
  260.   { 1, "longjmperror",vp,    "()",        "",        },
  261.   { 1, "lseek",    vp,    "(%d, %d, %d)",    "%d",        },
  262.   { 1, "lstat",    vp,    "(\"%s\", $%lx)",        "%d",        },
  263.   { 1, "malloc",    vp,    "(%d)",        "$%lx",        },
  264.   { 1, "memalign",    vp,    "(%d, %d)",    "$%lx",        },
  265.   { 1, "memccpy",    vp,    "($%lx, $%lx, %d, %d)", "$%lx",        },
  266.   { 1, "memchr",    vp,    "($%lx, %d, %d)",    "$%lx",        },
  267.   { 1, "memcmp",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  268.   { 1, "memcpy",    vp,    "($%lx, $%lx, %d)",    "$%lx",        },
  269.   { 1, "memmove",    vp,    "($%lx, $%lx, %d)",    "$%lx",        },
  270.   { 1, "memset",    vp,    "($%lx, %d, %d)",    "$%lx",        },
  271.   { 1, "mkdir",    vp,    "(\"%s\", %o)",    "%d",        },
  272.   { 1, "mkstemp",    vp,    "(\"%s\")",        "%d",        },
  273.   { 1, "mktemp",    vp,    "(\"%s\")",        "\"%s\"",        },
  274.   { 1, "open",    vp_open,    "(\"%s\", \"%s\", %o)",    "%d",        },
  275.   { 1, "pause",    vp,    "()",    "%d",        },
  276.   { 1, "perror",    vp,    "(\"%s\")",    "%d",        },
  277.   { 1, "pipe",    vp_pipe,    "([%d, %d])",    "%d",        },
  278.   { 1, "psig",    vp,    "bad call",    "",        },
  279.   { 1, "psignal",    vp,    "(%d, \"%s\")",    "",        },
  280.   { 1, "putenv",    vp,    "(\"%s\")",        "",        },
  281.   { 1, "qsort",    vp,    "($%lx, %d, %d, $%lx)",    "",        },
  282.   { 1, "rand",    vp,    "()",    "%d",        },
  283.   { 1, "random",    vp,    "()",    "%d",        },
  284.   { 1, "read",    vp,    "(%d, $%lx, %d)",    "%d",        },
  285.   { 1, "readlink",    vp,    "(\"%s\", \"%s\", %d)",        "%d",        },
  286.   { 1, "readv",    vp,    "(%d, $%lx, %d)",    "%d",        },
  287.   { 1, "realloc",    vp,    "($%lx, %d)",    "$%lx",        },
  288.   { 1, "remove",    vp,    "(\"%s\")",    "%d",        },
  289.   { 1, "remque",    vp,    "($%lx)",    "",        },
  290.   { 1, "rename",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  291.   { 1, "rindex",    vp,    "(\"%s\", %c)",    "$%lx",        },
  292.   { 1, "rmdir",    vp,    "(\"%s\")",    "%d",        },
  293.   { 1, "select",    vp,    "(%d, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  294.   { 1, "setenv",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  295.   { 1, "setgroups",    vp,    "(%d, $%lx)",    "%d",        },
  296.   { 1, "sethostname",vp,    "(\"%s\", %d)",    "%d",        },
  297.   { 1, "setitimer",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  298.   { 1, "setjmp",    vp,    "($%lx, %d)",    "%d",        },
  299.   { 1, "setpgrp",    vp,    "($%lx, $%lx)",    "%d",        },
  300.   { 1, "setpriority",vp,    "(%d, %d, %d)",    "%d",        },
  301.   { 1, "setrlimit",    vp,    "(%d, $%lx)",    "%d",        },
  302.   { 1, "settimeofday",vp,    "($%lx, $%lx)",    "%d",        },
  303.   { 1, "sigaction",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  304.   { 1, "sigaddset",    vp,    "($%lx, %d)",    "%d",        },
  305.   { 1, "sigblock",    vp,    "($%lx)",    "%d",        },
  306.   { 1, "sigdelset",    vp,    "($%lx, %d)",    "%d",        },
  307.   { 1, "sigemptyset",vp,    "($%lx)",    "%d",        },
  308.   { 1, "sigfillset",    vp,    "($%lx)",    "%d",        },
  309.   { 1, "siginterrupt",vp,    "(%d, %d)",    "%d",        },
  310.   { 1, "sigismember",vp,    "($%lx, %d)",    "%d",        },
  311.   { 1, "siglongjmp",    vp,    "($%lx, %d)",    "%d",        },
  312.   { 1, "signal",    vp,    "(%d, $%lx)",    "$%lx",        },
  313.   { 1, "sigpause",    vp,    "($%lx)",    "%d",        },
  314.   { 1, "sigpending",    vp,    "($%lx)",    "%d",        },
  315.   { 1, "sigprocmask",vp,    "(%d, $%lx, $%lx)",     "%d",        },
  316.   { 1, "sigreturn",    vp,    "($%lx)",    "%d",        },
  317.   { 1, "sigsetjmp",    vp,    "($%lx, %d)",    "%d",        },
  318.   { 1, "sigsetmask",    vp,    "($%lx)",    "$%lx",        },
  319.   { 1, "sigstack",    vp,    "($%lx)",    "%d",        },
  320.   { 1, "sigsuspend",    vp,    "($%lx)",    "%d",        },
  321.   { 1, "sigvec",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  322.   { 1, "sleep",    vp,    "(%d)",    "%d",        },
  323.   { 1, "srand",    vp,    "(%d)",    "",        },
  324.   { 1, "srandom",    vp,    "(%d)",    "",        },
  325.   { 1, "stat",    vp,    "(\"%s\", $%lx)",    "%d",        },
  326.   { 1, "strcasecmp",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  327.   { 1, "strcat",    vp,    "(\"%"LWS"s\", \"%"LWS"s\")",    "$%lx",        },
  328.   { 1, "strchr",    vp,    "(\"%s\", %c)",    "$%lx",        },
  329.   { 1, "strcmp",    vp,    "(\"%"LWS"s\", \"%"LWS"s\")",    "%d",        },
  330.   { 1, "strcoll",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  331.   { 1, "strcpy",    vp,    "($%lx, \"%s\")",    "$%lx",        },
  332.   { 1, "strcspn",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  333.   { 1, "strdup",    vp,    "(\"%s\")",        "$%lx",        },
  334.   { 1, "strerror",    vp,    "(%d)",        "\"%s\"",        },
  335.   { 1, "strftime",    vp,    "(\"%s\", %d, \"%s\", $%lx)", "%d",        },
  336.   { 1, "strlen",    vp,    "(\"%s\")",    "%d",        },
  337.   { 1, "strmode",    vp,    "(\"%s\", %o)",    "",        },
  338.   { 1, "strncasecmp",vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  339.   { 1, "strncat",    vp,    "(\"%s\", \"%s\", %d)",    "$%lx",        },
  340.   { 1, "strncmp",    vp,    "(\"%"LWS"s\", \"%"LWS"s\", %d)",    "%d",        },
  341.   { 1, "strncpy",    vp,    "($%lx, \"%s\", %d)", "$%lx",        },
  342.   { 1, "strpbrk",    vp,    "(\"%s\", \"%s\")",    "$%lx",        },
  343.   { 1, "strrchr",    vp,    "(\"%s\", %c)",    "$%lx",        },
  344.   { 1, "strsep",    vp,    "($%lx, \"%s\")",    "\"%s\"",        },
  345.   { 1, "strspn",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  346.   { 1, "strstr",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  347.   { 1, "strtok",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  348.   { 1, "strtol",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  349.   { 1, "strtoul",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  350.   { 1, "strunvis",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  351.   { 1, "strvis",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  352.   { 1, "strvisx",    vp,    "(\"%s\", \"%s\", %d, %d)",    "%d",        },
  353.   { 1, "strxfrm",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  354.   { 1, "swab",    vp,    "($%lx, $%lx, %d)",    "",        },
  355.   { 1, "symlink",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  356.   { 1, "system",    vp,    "(\"%s\")",    "%d",        },
  357.   { 1, "tcgetattr",    vp,    "(%d, $%lx)",    "%d",        },
  358.   { 1, "tcgetpgrp",    vp,    "(%d)",    "$%lx",        },
  359.   { 1, "tcsetattr",    vp,    "(%d, $%lx)",    "%d",        },
  360.   { 1, "tcsetpgrp",    vp,    "(%d, $%lx)",    "%d",        },
  361.   { 1, "time",    vp,    "($%lx)",    "%d",        },
  362.   { 1, "tmpnam",    vp,    "(\"%s\")",    "\"%s\"",        },
  363.   { 1, "tolower",    vp,    "(%c)",    "%c",        },
  364.   { 1, "toupper",    vp,    "(%c)", "%c",        },
  365.   { 1, "truncate",    vp,    "(\"%s\", %d)",    "%d",        },
  366.   { 1, "ualarm",    vp,    "(%d, %d)",    "%d",        },
  367.   { 1, "umask",    vp,    "(%o)",    "%d",        },
  368.   { 1, "unlink",    vp,    "(\"%s\")",    "%d",        },
  369.   { 1, "unvis",    vp,    "(\"%s\", %c, $%lx, %d)",    "%d",        },
  370.   { 1, "usleep",    vp,    "(%d)",    "%d",        },
  371.   { 1, "utime",    vp,    "(\"%s\", $%lx)",    "%d",        },
  372.   { 1, "utimes",    vp,    "(\"%s\", $%lx)",    "%d",        },
  373.   { 1, "valloc",    vp,    "(%d)",    "$%lx",        },
  374.   { 1, "vis",    vp,    "(\"%s\", %c, $%lx, %d)",    "\"%s\"",        },
  375.   { 1, "write",    vp,    "(%d, $%lx, %d)",    "%d",        },
  376.   { 1, "writev",    vp,    "(%d, $%lx, %d)",    "%d",        },
  377.   { 1, "_exit",    vp,    "(%d)",    "",        },
  378.   { 1, "_longjmp",    vp,    "($%lx, %d)",    "",        },
  379.   { 1, "_setjmp",    vp,    "($%lx)",    "%d",        },
  380.   { 1, "_wb_parse",    vp,    "($%lx, $%lx, \"%s\")",    "%d",        },
  381.   { 1, "_cli_parse",    vp,    "($%lx, %d, \"%s\", $%lx, $%lx)",    "%d",        },
  382.   { 1, "_main",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  383.   { 0, "__adddf3",    vp,    "(%g, %g)",    "%g",        },
  384.   { 0, "__addsf3",    vp,    "(%g, %g)",    "%g",        },
  385.   { 0, "__ashldi3",    vp,    "($%0lx%08lx, %d)", "$%0lx%08lx",        },
  386.   { 0, "__ashlsi3",    vp,    "(%d)",    "%d",        },
  387.   { 0, "__ashrdi3",    vp,    "($%0lx%08lx, %d)", "$%0lx%08lx",        },
  388.   { 0, "__ashrsi3",    vp,    "(%d)",    "%d",        },
  389.   { 0, "__clear_cache",vp,    "()","",        },
  390.   { 0, "__cmpdf2",    vp,    "(%g, %g)",    "%d",        },
  391.   { 0, "__cmpdi2",    vp,    "($%0lx%08lx, $%0lx%08lx)", "%d",        },
  392.   { 0, "__cmpsf2",    vp,    "(%g, %g)",    "%d",        },
  393.   { 0, "__divdf3",    vp,    "(%g, %g)",    "%g",        },
  394.   { 0, "__divdi3",    vp,    "($%0lx%08lx, $%0lx%08lx)", "$%0lx%08lx",        },
  395.   { 0, "__divsf3",    vp,    "(%g, %g)",    "%g",        },
  396.   { 0, "__divsi3",    vp,    "(%d, %d)",    "%d",        },
  397.   { 0, "__eqdf2",    vp,    "(%g, %g)",    "%d",        },
  398.   { 0, "__eqsf2",    vp,    "(%g, %g)",    "%d",        },
  399.   { 0, "__extendsfdf2",vp,    "(%g)",    "%g",        },
  400.   { 0, "__fixdfdi",    vp,    "(%g)", "$%0lx%08lx)",        },
  401.   { 0, "__fixdfsi",    vp,    "(%g)",    "%g",        },
  402.   { 0, "__fixsfdi",    vp,    "(%g)",    "$%0lx%08lx",        },
  403.   { 0, "__fixsfsi",    vp,    "(%g)",    "%d",        },
  404.   { 0, "__fixunsdfdi",vp,    "(%g)",    "$%0lx%08lx",        },
  405.   { 0, "__fixunsdfsi",vp,    "(%g)",    "%d",        },
  406.   { 0, "__fixunssfdi",vp,    "(%g)",    "$%0lx%08lx",        },
  407.   { 0, "__fixunssfsi",vp,    "(%g)",    "%d",        },
  408.   { 0, "__floatdidf",vp,    "($%0lx%08lx)","%g",        },
  409.   { 0, "__floatdisf",vp,    "($%0lx%08lx)","%g",        },
  410.   { 0, "__floatsidf",vp,    "(%d)",    "%g",        },
  411.   { 0, "__floatsisf",vp,    "(%d)",    "%g",        },
  412.   { 0, "__gedf2",    vp,    "(%g, %g)",    "%d",        },
  413.   { 0, "__gesf2",    vp,    "(%g, %g)",    "%d",        },
  414.   { 0, "__gtdf2",    vp,    "(%g, %g)",    "%d",        },
  415.   { 0, "__gtsf2",    vp,    "(%g, %g)",    "%d",        },
  416.   { 0, "__ledf2",    vp,    "(%g, %g)",    "%d",        },
  417.   { 0, "__lesf2",    vp,    "(%g, %g)",    "%d",        },
  418.   { 0, "__lshldi3",    vp,    "($%0lx%08lx, %d)", "($%0lx%08lx)",        },
  419.   { 0, "__lshlsi3",    vp,    "(%d, %d)",    "%d",        },
  420.   { 0, "__lshrdi3",    vp,    "($%0lx%08lx, %d)", "($%0lx%08lx)",        },
  421.   { 0, "__lshrsi3",    vp,    "(%d, %d)",    "%d",        },
  422.   { 0, "__ltdf2",    vp,    "(%g, %g)",    "%d",        },
  423.   { 0, "__ltsf2",    vp,    "(%g, %g)",    "%d",        },
  424.   { 0, "__moddi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  425.   { 0, "__modsi3",    vp,    "(%d, %d)",    "%d",        },
  426.   { 0, "__muldf3",    vp,    "(%g, %g)",    "%g",        },
  427.   { 0, "__muldi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  428.   { 0, "__mulsf3",    vp,    "(%g, %g)",    "%g",        },
  429.   { 0, "__mulsi3",    vp,    "(%d, %d)",    "%d",        },
  430.   { 0, "__nedf2",    vp,    "(%g, %g)",    "%d",        },
  431.   { 0, "__negdf2",    vp,    "(%g)",    "%g",        },
  432.   { 0, "__negdi2",    vp,    "($%0lx%08lx)",    "$%0lx%08lx",        },
  433.   { 0, "__negsf2",    vp,    "(%g)",    "%g",        },
  434.   { 0, "__nesf2",    vp,    "(%g)",    "%g",        },
  435.   { 0, "__subdf3",    vp,    "(%g, %g)",    "%g",        },
  436.   { 0, "__subsf3",    vp,    "(%g, %g)",    "%g",        },
  437.   { 0, "__truncdfsf2",vp,    "(%g)",    "%g",        },
  438.   { 0, "__ucmpdi2",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "%d",        },
  439.   { 0, "__udivdi3",    vp,    "($%0lx%08lx, $%0lx%08lx)", "$%0lx%08lx",        },
  440.   { 0, "__udivmoddi4",vp,    "($%0lx%08lx, $%0lx%08lx, $%0lx%08lx, $%0lx%08lx)", "",        },
  441.   { 0, "__udivsi3",    vp,    "(%d, %d)",    "%d",        },
  442.   { 0, "__umoddi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  443.   { 0, "__umodsi3",    vp,    "(%d, %d)",    "%d",        },
  444.   { 1, "ix_get_vars",vp,    "($%lx, $%lx)",    "",        },
  445.   { 1, "modf",    vp,    "(%g, $%lx)",    "%g",        },
  446.   { 1, "opendir",    vp,    "(\"%s\")",    "$%lx",        },
  447.   { 1, "readdir",    vp,    "($%lx)",    "$%lx",        },
  448.   { 1, "rewinddir",    vp,    "($%lx)",    "",        },
  449.   { 1, "closedir",    vp,    "($%lx)",    "",        },
  450.   { 1, "telldir",    vp,    "($%lx)",    "%d",        },
  451.   { 1, "seekdir",    vp,    "($%lx, %d)",    "%d",        },
  452.   { 1, "ssystem",    vp,    "(\"%s\")",    "%d",        },
  453.   { 1, "isinf",    vp,    "(%g)",    "%d",        },
  454.   { 1, "isnan",    vp,    "(%g)",    "%d",        },
  455.   { 1, "ldexp",    vp,    "(%g, %d)",    "%g",        },
  456.   { 1, "achmod",    vp,    "(\"%s\", $%lx)",    "%d",        },
  457.   { 1, "stricmp",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  458.   { 1, "strnicmp",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  459.   { 1, "atan",    vp,    "(%g)",    "%g",        },
  460.   { 1, "sin",    vp,    "(%g)",    "%g",        },
  461.   { 1, "cos",    vp,    "(%g)",    "%g",        },
  462.   { 1, "tan",    vp,    "(%g)",    "%g",        },
  463.   { 1, "sincos",    vp,    "($%lx, %g)",    "%g",        },
  464.   { 1, "sinh",    vp,    "(%g)",    "%g",        },
  465.   { 1, "cosh",    vp,    "(%g)",    "%g",        },
  466.   { 1, "tanh",    vp,    "(%g)",    "%g",        },
  467.   { 1, "exp",    vp,    "(%g)",    "%g",        },
  468.   { 1, "log",    vp,    "(%g)",    "%g",        },
  469.   { 1, "pow",    vp,    "(%g, %g)",    "%g",        },
  470.   { 1, "sqrt",    vp,    "(%g)",    "%g",        },
  471.   { 1, "asin",    vp,    "(%g)",    "%g",        },
  472.   { 1, "acos",    vp,    "(%g)",    "%g",        },
  473.   { 1, "log10",    vp,    "(%g)",    "%g",        },
  474.   { 1, "fabs",    vp,    "(%g)",    "%g",        },
  475.   { 1, "initstate",    vp,    "(%d, $%lx, %d)",    "$%lx",        },
  476.   { 1, "setstate",    vp,    "($%lx)",    "$%lx",        },
  477.   { 1, "ix_exec_entry",vp,    "(%d, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  478.   { 1, "ix_get_vars2",vp,    "(%d, $%lx, $%lx, $%lx, $%lx, $%lx, $%lx)",    "",        },
  479.   { 1, "execve",    vp,    "(\"%s\", $%lx, $%lx)",    "%d",        },
  480.   { 1, "execl",    vp,    "(\"%s\", \"%s\", \"%s\", ...)",    "%d",        },
  481.   { 1, "execv",    vp,    "(\"%s\", $%lx)",    "%d",        },
  482.   { 1, "execle",    vp,    "(\"%s\", $%lx, $%lx)",    "%d",        },
  483.   { 1, "execlp",    vp,    "(\"%s\", \"%s\", \"%s\", ...)",    "%d",        },
  484.   { 1, "execvp",    vp,    "(\"%s\", $%lx)",    "%d",        },
  485.   { 1, "vfork",    vp,    "()",    "%d",        },
  486.   { 1, "wait4",    vp,    "($%lx, $%lx, $%lx, $%lx)",    "%d",        },
  487.   { 1, "wait",    vp,    "($%lx)",    "%d",        },
  488.   { 1, "wait3",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  489.   { 1, "waitpid",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  490.   { 1, "vfork_resume",vp,    "()",    "",        },
  491.   { 1, "profil",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  492.   { 1, "ptrace",    vp,    "(%d, $%lx, $%lx, $%lx)",    "%d",        },
  493.   { 1, "clearerr",    vp,    "($%lx)",    "",        },
  494.   { 1, "fclose",    vp,    "($%lx)",    "%d",        },
  495.   { 1, "fdopen",    vp,    "(%d, \"%s\")",    "$%lx",        },
  496.   { 1, "feof",    vp,    "($%lx)",    "%d",        },
  497.   { 1, "ferror",    vp,    "($%lx)",    "%d",        },
  498.   { 1, "fflush",    vp,    "($%lx)",    "%d",        },
  499.   { 1, "fgetc",    vp,    "($%lx)",    "%d",        },
  500.   { 1, "fgetline",    vp,    "($%lx, $%lx)",    "\"%s\"",        },
  501.   { 1, "fgetpos",    vp,    "($%lx, $%lx)",    "%d",        },
  502.   { 1, "fgets",    vp,    "(\"%s\", %d, $%lx)",    "$%lx",        },
  503.   { 1, "fileno",    vp,    "($%lx)",    "%d",        },
  504.   { 1, "f_prealloc",    vp,    "()",    "",        },
  505.   { 1, "fopen",    vp,    "(\"%s\", \"%s\")",    "$%lx",        },
  506.   { 1, "fprintf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  507.   { 1, "fpurge",    vp,    "($%lx)",    "%d",        },
  508.   { 1, "fputc",    vp,    "(%d, $%lx)",    "%d",        },
  509.   { 1, "fputs",    vp,    "(\"%s\", $%lx)",    "%d",        },
  510.   { 1, "fread",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  511.   { 1, "freopen",    vp,    "(\"%s\", \"%s\", $%lx)",    "$%lx",        },
  512.   { 1, "fscanf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  513.   { 1, "fseek",    vp,    "($%lx, %d, %d)",    "%d",        },
  514.   { 1, "fsetpos",    vp,    "($%lx, $%lx)",    "%d",        },
  515.   { 1, "ftell",    vp,    "($%lx)",    "%d",        },
  516.   { 1, "funopen",    vp,    "($%lx, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  517.   { 1, "fwrite",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  518.   { 1, "getc",    vp,    "($%lx)",    "%d",        },
  519.   { 1, "getchar",    vp,    "()",    "%d",        },
  520.   { 1, "gets",    vp,    "(\"%s\")",    "\"%s\"",        },
  521.   { 1, "getw",    vp,    "($%lx)",    "%d",        },
  522.   { 1, "printf",    vp,    "(\"%s\", ...)",    "%d",        },
  523.   { 1, "putc",    vp,    "(%d, $%lx)",    "%d",        },
  524.   { 1, "putchar",    vp,    "(%d)",    "%d",        },
  525.   { 1, "puts",    vp,    "(\"%s\")",    "%d",        },
  526.   { 1, "putw",    vp,    "(%d, $%lx)",    "%d",        },
  527.   { 1, "rewind",    vp,    "($%lx)",    "%d",        },
  528.   { 1, "scanf",    vp,    "(\"%s\", ...)",    "%d",        },
  529.   { 1, "setbuf",    vp,    "($%lx, $%lx)",    "",        },
  530.   { 1, "setbuffer",    vp,    "($%lx, $%lx, %d)",    "",        },
  531.   { 1, "setlinebuf",    vp,    "($%lx)",    "",        },
  532.   { 1, "setvbuf",    vp,    "($%lx, $%lx, %d, %d)",    "%d",        },
  533.   { 1, "snprintf",    vp,    "(\"%s\", %d, \"%s\", ...)",    "%d",        },
  534.   { 1, "sprintf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  535.   { 1, "sscanf",    vp,    "(\"%s\", \"%s\", ...)",    "%d",        },
  536.   { 1, "tempnam",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  537.   { 1, "tmpfile",    vp,    "()",    "$%lx",        },
  538.   { 1, "ungetc",    vp,    "(%d, $%lx)",    "%d",        },
  539.   { 1, "vfprintf",    vp,    "($%lx, \"%s\", $%lx)",    "%d",        },
  540.   { 1, "vprintf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  541.   { 1, "vscanf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  542.   { 1, "vsnprintf",    vp,    "(\"%s\", %d, \"%s\", $%lx)",    "%d",        },
  543.   { 1, "vsprintf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  544.   { 1, "vsscanf",    vp,    "(\"%s\", \"%s\", $%lx)",    "%d",        },
  545.   { 1, "crypt",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  546.   { 1, "des_cipher",    vp,    "(\"%s\", \"%s\", %d, %d)",    "%d",        },
  547.   { 1, "des_setkey",    vp,    "(\"%s\")",    "%d",        },
  548.   { 1, "encrypt",    vp,    "(\"%s\", %d)", "%d",        },
  549.   { 1, "setkey",    vp,    "(\"%s\")",    "%d",        },
  550.   { 1, "fnmatch",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  551.   { 1, "fts_children",vp,    "($%lx)",    "$%lx",        },
  552.   { 1, "fts_close",    vp,    "($%lx)",    "%d",        },
  553.   { 1, "fts_open",    vp,    "($%lx, %d, $%lx)",    "$%lx",        },
  554.   { 1, "fts_read",    vp,    "($%lx)",    "$%lx",        },
  555.   { 1, "fts_set",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  556.   { 1, "cuserid",    vp,    "(\"%s\")",    "\"%s\"",        },
  557.   { 1, "getlogin",    vp,    "()",    "\"%s\"",        },
  558.   { 1, "glob",    vp,    "(\"%s\", %d, $%lx, $%lx)",    "%d",        },
  559.   { 1, "globfree",    vp,    "($%lx)",    "",        },
  560.   { 1, "__amiga_filehandle",vp,    "(%d)",    "$%lx",        },
  561.   { 1, "times",    vp,    "($%lx)",    "$%lx",        },
  562.   { 1, "mblen",    vp,    "(\"%s\", %d)",    "%d",        },
  563.   { 1, "mbstowcs",    vp,    "($%lx, \"%s\", %d)",    "%d",        },
  564.   { 1, "mbtowc",    vp,    "($%lx, \"%s\", %d)",    "%d",        },
  565.   { 1, "wcstombs",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  566.   { 1, "wctomb",    vp,    "(\"%s\", $%lx)",    "%d",        },
  567.   { 1, "heapsort",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  568.   { 1, "radixsort",    vp,    "($%lx, %d, \"%s\", %d)",    "%d",        },
  569.   { 0, "__sflush",    vp,    "()",    "",        },
  570.   { 0, "__slbexpand",vp,    "()",    "",        },
  571.   { 0, "__sfp",    vp,    "()",    "",        },
  572.   { 0, "__sflags",    vp,    "()",    "",        },
  573.   { 0, "__sfvwrite",    vp,    "()",    "",        },
  574.   { 0, "__smakebuf",    vp,    "()",    "",        },
  575.   { 0, "__srefill",    vp,    "()",    "",        },
  576.   { 0, "__srget",    vp,    "()",    "",        },
  577.   { 0, "__sclose",    vp,    "()",    "",        },
  578.   { 0, "__sread",    vp,    "()",    "",        },
  579.   { 0, "__sseek",    vp,    "()",    "",        },
  580.   { 0, "__swrite",    vp,    "()",    "",        },
  581.   { 0, "__svfscanf",    vp,    "()",    "",        },
  582.   { 0, "__swbuf",    vp,    "()",    "",        },
  583.   { 0, "__swsetup",    vp,    "()",    "",        },
  584.   { 1, "fchdir",    vp,    "(%d)",    "%d",        },
  585.   { 1, "strtod",    vp,    "(\"%s\", $%lx)",    "%g",        },
  586.   { 1, "setgrent",    vp,    "()",    "",        },
  587.   { 1, "getgrent",    vp,    "()",    "",        },
  588.   { 1, "endgrent",    vp,    "()",    "",        },
  589.   { 1, "ix_resident",vp,    "(%d, $%lx, %d, $%lx)",    "",        },
  590.   { 1, "ix_geta4",    vp,    "()",    "",        },
  591.   { 1, "ix_check_cpu",vp,    "(%d)",    "",        },
  592.   { 1, "tracecntl",    vp,    "(%d, $%lx)",    "%d",        },
  593.   { 1, "sysconf",    vp,    "(%d)",    "%d",    },
  594.   { 1, "pathconf",    vp,    "(\"%s\", %d)", "%d",    },
  595.   { 1, "fpathconf",    vp,    "(%d, %d)",    "%d",    },
  596.   { 1, "getfsstat",    vp,    "($%lx, %d, %d)", "%d",    },
  597.   { 1, "fstatfs",    vp,    "(%d, $%lx)", "%d", },
  598.   { 1, "getmntinfo",    vp,    "($%lx, %d)",    "%d", },
  599.   { 1, "getgrnam",    vp,    "(\"%s\")",    "%d", },
  600.   { 1, "endpwent",    vp,    "()",    "", },
  601.   { 1, "sync",        vp,    "()",    "", },
  602.   { 1, "fork",        vp,    "()",    "%d", },
  603.   { 1, "mkfifo",    vp,    "(\"%s\", %o)",    "%d", },
  604.   { 1, "mknod",        vp,    "(\"%s\", %o)",    "%d", },
  605.   { 1, "setuid",    vp,    "(%d)",    "%d", },
  606.   { 1, "nice",        vp,    "(%d)",    "%d", },
  607.   { 1, "floor",        vp,    "(%g)",    "%g", },
  608.   { 1, "ceil",        vp,    "(%g)",    "%g", },
  609.   { 1, "setgid",    vp,    "(%d)",    "%d", },
  610.   { 1, "vfork",        vp,    "()",    "%d", },
  611. };
  612.  
  613. /* should help make things less mystic... */
  614. #define TP_SCALL(tp) (tp->tp_argv[0])
  615. /* this is only valid if !tp->tp_is_entry */
  616. #define TP_RESULT(tp) (tp->tp_argv[1])
  617. #define TP_ERROR(tp) (* tp->tp_errno)
  618. /* tp_argv[2] is the return address */
  619. #define TP_FIRSTARG(tp) (tp->tp_argv[3])
  620.  
  621. void
  622. print_call (FILE *output, struct trace_packet *tp)
  623. {
  624.   char line[OUT_WIDTH+2];    /* for \n\0 */
  625.   char *argfield;
  626.   int space, len;
  627.   struct call *c;
  628.  
  629.   space = sizeof (line) - 1;
  630.   len = sprintf (line, "$%lx: %c", tp->tp_message.mn_ReplyPort,
  631.                tp->tp_is_entry ? '>' : '<');
  632.   argfield = line + len;
  633.   space -= len;
  634.  
  635.   if (TP_SCALL (tp) > sizeof (call_table) / sizeof (struct call))
  636.     {
  637.       if (tp->tp_is_entry)
  638.         sprintf (argfield, "SYS_%d()\n", TP_SCALL (tp));
  639.       else
  640.         sprintf (argfield, "SYS_%d() = $%lx (%d)\n", 
  641.           TP_SCALL (tp), TP_RESULT (tp), TP_ERROR (tp));
  642.     }
  643.   else
  644.     {
  645.       c = call_table + TP_SCALL (tp);
  646.  
  647.       if ((!print_all && !c->interesting) || 
  648.       (skip_sigsetmask && TP_SCALL (tp) == SYS_sigsetmask))
  649.     return;
  650.  
  651.       /* we can write space-1 real characters in the buffer, \n is not counted */
  652.       c->func (argfield, space-1, c, tp);
  653.     }
  654.  
  655.   fputs (line, output);
  656. }
  657.  
  658. /* the program contained a bug du to the fact that
  659.  * when snprintf or vsnprintf are called with a zero or negative size,
  660.  * they return -1 as an error marker but not any length.
  661.  */
  662. void
  663. vp (char *buf, int len, struct call *c, struct trace_packet *tp)
  664. {
  665.   int nl = snprintf (buf, len+1, "%s", c->name);
  666.  
  667.   len -= nl; if (len <= 0) goto finish;
  668.   buf += nl;
  669.   if (tp->tp_is_entry || !c->rfmt[0])
  670.     vsnprintf (buf, len+1, c->fmt, (_VA_LIST_) & TP_FIRSTARG (tp));
  671.   else
  672.     {
  673.       nl = vsnprintf (buf, len+1, c->fmt, (_VA_LIST_) & TP_FIRSTARG (tp));
  674.       len -= nl; if (len <= 0) goto finish;
  675.       buf += nl;
  676.       nl = snprintf (buf, len+1, "=");
  677.       len -= nl; if (len <= 0) goto finish;
  678.       buf += nl;
  679.       nl = vsnprintf (buf, len+1, c->rfmt, (_VA_LIST_) & TP_RESULT (tp));
  680.       len -= nl; if (len <= 0) goto finish;
  681.       buf += nl;
  682.       nl = snprintf (buf, len+1, " (%d)", TP_ERROR (tp));
  683.     }
  684.  
  685.   finish:
  686.   strcat (buf, "\n");
  687. }
  688.  
  689. const char *
  690. get_fcntl_cmd (int cmd)
  691. {
  692.   switch (cmd)
  693.     {
  694.     case F_DUPFD:
  695.     return "F_DUPFD";
  696.  
  697.     case F_GETFD:
  698.     return "F_GETFD";
  699.  
  700.     case F_SETFD:
  701.     return "F_SETFD";
  702.  
  703.     case F_GETFL:
  704.     return "F_GETFL";
  705.  
  706.     case F_SETFL:
  707.     return "F_SETFL";
  708.     
  709.     case F_GETOWN:
  710.     return "F_GETOWN";
  711.  
  712.     case F_SETOWN:
  713.     return "F_SETOWN";
  714.  
  715.     case F_GETLK:
  716.     return "F_GETLK";
  717.  
  718.     case F_SETLK:
  719.     return "F_SETLK";
  720.  
  721.     case F_SETLKW:
  722.     return "F_SETLKW";
  723.  
  724.     default:
  725.     return "F_unknown";
  726.     }
  727. }
  728.  
  729. char *
  730. get_open_mode (int mode)
  731. {
  732.   static char buf[120];
  733.   
  734.   switch (mode & O_ACCMODE)
  735.     {
  736.     case O_RDONLY: 
  737.       strcpy (buf, "O_RDONLY");
  738.       break;
  739.       
  740.     case O_WRONLY:
  741.       strcpy (buf, "O_WRONLY");
  742.       break;
  743.       
  744.     case O_RDWR:
  745.       strcpy (buf, "O_RDWR");
  746.       break;
  747.       
  748.     default:
  749.       strcpy (buf, "O_illegal");
  750.       break;
  751.     }
  752.  
  753. #define ADD(flag) \
  754.   if (mode & flag) strcat (buf, "|" #flag);
  755.  
  756.   ADD (O_NONBLOCK);  
  757.   ADD (O_APPEND);
  758.   ADD (O_SHLOCK);
  759.   ADD (O_EXLOCK);
  760.   ADD (O_ASYNC);
  761.   ADD (O_FSYNC);
  762.   ADD (O_CREAT);
  763.   ADD (O_TRUNC);
  764.   ADD (O_EXCL);
  765. #undef ADD
  766.   
  767.   return buf;
  768. }
  769.  
  770. char *
  771. get_ioctl_cmd (int cmd)
  772. {
  773.   static char buf[12];
  774.  
  775.   /* only deal with those commands that are really implemented somehow in
  776.      ixemul.library. The others are dummies anyway, so they don't matter */
  777.  
  778.   switch (cmd)
  779.     {
  780.     case FIONREAD:
  781.       return "FIONREAD";
  782.  
  783.     case FIONBIO:
  784.       return "FIONBIO";
  785.  
  786.     case FIOASYNC:
  787.       /* not yet implemented, but important to know if some program tries
  788.          to use it ! */
  789.       return "FIOASYNC";
  790.  
  791.     case TIOCGETA:
  792.       return "TIOCGETA";
  793.  
  794.     case TIOCSETA:
  795.       return "TIOCSETA";
  796.  
  797.     case TIOCSETAW:
  798.       return "TIOCSETAW";
  799.  
  800.     case TIOCSETAF:
  801.       return "TIOCSETAF";
  802.  
  803.     case TIOCGETP:
  804.       return "TIOCGETP";
  805.  
  806.     case TIOCSETN:
  807.       return "TIOCSETN";
  808.  
  809.     case TIOCSETP:
  810.       return "TIOCSETP";
  811.  
  812.     case TIOCGWINSZ:
  813.       return "TIOCGWINSZ";
  814.  
  815.     case TIOCOUTQ:
  816.       return "TIOCOUTQ";
  817.  
  818.     case TIOCSWINSZ:
  819.       return "TIOCSWINSZ";
  820.       
  821.     default:
  822.       sprintf (buf, "$%lx", cmd);
  823.       return buf;
  824.     }
  825. }
  826.  
  827.  
  828. void
  829. vp_fcntl (char *buf, int len, struct call *c, struct trace_packet *tp)
  830. {
  831.   long *argv = & TP_FIRSTARG (tp);
  832.   
  833.   if (tp->tp_is_entry)
  834.     if (argv[1] == F_GETFL || argv[1] == F_SETFL)
  835.       snprintf (buf, len+1, "fcntl(%d, %s, %s)",
  836.             argv[0], get_fcntl_cmd (argv[1]), get_open_mode (argv[2]));
  837.     else
  838.       snprintf (buf, len+1, "fcntl(%d, %s, %d)",
  839.             argv[0], get_fcntl_cmd (argv[1]), argv[2]);
  840.   else
  841.     if (argv[1] == F_GETFL || argv[1] == F_SETFL)
  842.       snprintf (buf, len+1, "fcntl(%d, %s, %s) = %d (%d)",
  843.             argv[0], get_fcntl_cmd (argv[1]), 
  844.         get_open_mode (argv[2]), TP_RESULT (tp), TP_ERROR (tp));
  845.     else
  846.       snprintf (buf, len+1, "fcntl(%d, %s, %d) = %d (%d)",
  847.             argv[0], get_fcntl_cmd (argv[1]), argv[2], 
  848.         TP_RESULT (tp), TP_ERROR (tp));
  849.  
  850.   strcat (buf, "\n");
  851. }
  852.  
  853.  
  854. void
  855. vp_ioctl (char *buf, int len, struct call *c, struct trace_packet *tp)
  856. {
  857.   long *argv = & TP_FIRSTARG (tp);
  858.   
  859.   if (tp->tp_is_entry)
  860.     snprintf (buf, len+1, "ioctl(%d, %s, $%lx)",
  861.           argv[0], get_ioctl_cmd (argv[1]), argv[2]);
  862.   else
  863.     snprintf (buf, len+1, "ioctl(%d, %s, $%lx) = %d (%d)",
  864.           argv[0], get_ioctl_cmd (argv[1]), argv[2],
  865.           TP_RESULT (tp), TP_ERROR (tp));
  866.  
  867.   strcat (buf, "\n");
  868. }
  869.  
  870.  
  871. void
  872. vp_open (char *buf, int len, struct call *c, struct trace_packet *tp)
  873. {
  874.   long *argv = & TP_FIRSTARG (tp);
  875.  
  876.   if (tp->tp_is_entry)
  877.     snprintf (buf, len+1, "open(\"%s\", %s)", argv[0], get_open_mode (argv[1]));
  878.   else
  879.     snprintf (buf, len+1, "open(\"%s\", %s) = %d (%d)", argv[0], 
  880.           get_open_mode (argv[1]), TP_RESULT (tp), TP_ERROR (tp));
  881.  
  882.   strcat (buf, "\n");
  883. }
  884.  
  885. void
  886. vp_pipe (char *buf, int len, struct call *c, struct trace_packet *tp)
  887. {
  888.   long *argv = & TP_FIRSTARG (tp);
  889.  
  890.   if (tp->tp_is_entry)
  891.     snprintf (buf, len+1, "pipe($%lx)", argv[0]);
  892.   else
  893.     {
  894.       int *pv = (int *) argv[0];
  895.     
  896.       snprintf (buf, len+1, "pipe([%d, %d]) = %d (%d)", 
  897.         pv[0], pv[1], TP_RESULT (tp), TP_ERROR (tp));
  898.     }
  899.  
  900.   strcat (buf, "\n");
  901. }
  902.